import type { FormItemRule, PaginationProps } from 'element-plus'
import {
  type VxeColumnProps,
  type VxeColumnSlotTypes,
  type VxeTableComponent,
  VxeTableDefines,
} from 'vxe-table'
import type { Fn, Recordable } from '@/types/global'
import type { ColEx, FormProps } from '@/components/BasicForm/src/types/form'
import type { CSSProperties, Ref, VNode } from 'vue'
import type { PaginationPropsType } from './pagination'
import type { ComponentType } from '@/components/BasicForm/src/componentMap'
export declare type SortOrder = 'ascend' | 'descend'

export type CellFormat =
  | string
  | ((text: string, record: Recordable, index: number) => string | number)
  | Map<string | number, any>

export interface BasicTableProps extends VxeTableComponent {
  /**
   * 接口请求对象
   * #param arg
   * #returns
   */
  api?: (...arg: any) => Promise<any>
  /**
   * 立即请求接口
   */
  immediate?: boolean
  /**
   * 额外的请求参数
   */
  searchInfo?: Recordable
  /**
   * 列配置
   */
  columns: BasicColumn[]
  /**
   * 是否显示序号列
   */
  showIndexColumn?: boolean
  /**
   * 是否叠加索引
   */
  reserveIndex: boolean
  /**
   *索引开始index
   */
  startIndex?: number

  /**
   * 是否显示边框 default（默认）, full（完整边框）, outer（外边框）, inner（内边框）, none（无边框）
   */
  border?: 'default' | 'full' | 'outer' | 'inner' | 'none'
  /**
   * 分页配置
   */
  pagination?: PaginationProps | boolean | PaginationPropsType
  /**
   * loading加载
   */
  loading?: boolean
  /**
   * 表单配置
   */
  formConfig?: Partial<FormProps>

  /**
   * 查询条件请求之前处理
   */
  handleSearchInfoFn?: Fn
  /**
   * 请求接口配置
   */
  fetchSetting?: Partial<FetchSetting>
  /**
   * 使用搜索表单
   */
  useSearchForm?: boolean
  /**
   * 数据
   */
  dataSource?: Recordable[]
  /**
   * 是否自动生成key
   */
  autoCreateKey?: boolean
  /**
   * 生成key 字段
   */
  rowKeyd?: string | ((record: Recordable) => string)
  /**
   * 请求之前处理参数
   */
  beforeFetch?: Fn
  /**
   * 自定义处理接口返回参数
   */
  afterFetch?: Fn
  /**
   * table 的最大高度。 合法的值为数字 计算高度时不能为字符串。（见官网）
   */
  maxHeight?: number
  /**
   *对齐方式
   */
  align?: '' | 'left' | 'center' | 'right' | null
  /**
   * 表头对齐方式， 若不设置该项，则使用表格的对齐方式
   */
  headerAlign?: '' | 'left' | 'center' | 'right' | null
  /**
   * 操作按钮配置
   */
  actionColumn?: BasicColumn | boolean
  /**
   * 表头单元格的 style 的回调方法，也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style
   */
  headerCellStyle?: Fn | CSSProperties
  /**
   * 是否为斑马纹
   */
  stripe?: boolean
  /**
   * 表格自适应高度计算结果会减去这个值 默认0
   */
  // resizeHeightOffset: number;
  /**
   * 是否可以自适应高度 默认true  (table外的插槽不参与计算 自适应父元素高度)
   */
  canResize: boolean
}

export interface BasicColumn<D = any> extends VxeColumnProps {
  /**
   * 列字段名
   */
  dataIndex?: string
  /**
   * 业务控制是否显示
   */
  ifShow?: boolean | ((column: BasicColumn) => boolean)
  /**
   * 多级
   */
  children?: BasicColumn[]
  /**
   *自定义渲染内容
   */
  customRender?: (opt: {
    row: D
    column: VxeTableDefines.ColumnInfo<D>
    cellValue: any
    index: number
  }) => VNode | string | any

  /** 自定义表头内容的模板*/
  headerRender?: (params: VxeColumnSlotTypes.HeaderSlotParams<D>) => any
  /**头部 自定义 slot，渲染组件 */
  headerSlot?: string
  /**展开 slot，渲染组件 */
  expandSlot?: string
  /**
   *自定义渲染展开
   */
  expandRender?: (params: VxeColumnSlotTypes.HeaderSlotParams<D>) => any
}

export interface TableFormConfigSchema {
  field: string // 字段名
  changeEvent?: string //表单更新事件名称
  label?: string | undefined //标签名
  /**是否在下面显示搜索内容 默认显示*/
  isBottomShow?: boolean

  labelWidth?: string | number //
  required?: boolean // 是否必须
  rules?: FormItemRule[] //验证规则
  rulesMessageJoinLabel?: boolean //	校验信息是否加入 label
  defaultValue?: any // 默认值
  component: ComponentType //组件
  colProps?: Partial<ColEx> // col参数
  componentProps?:
    | ((opt: {
        schema: TableFormConfigSchema
        formModel: Recordable
        field: string
        setSearchData: (schema: TableFormConfigSchema, value: any) => void
      }) => Recordable)
    | object //传递到子组件数据
  slot?: string //自定义 slot，渲染组件
  renderComponentContent?: (renderCallbackParams: RenderComponentContent) => any //自定义渲染组内部的 slot
  render?: ((renderCallbackParams: RenderComponentContent) => any) | VNode | VNode[] | string //自定义渲染组件
  isClearFetch?: boolean //组件内点击清空按钮是否请求数据
}
export interface RenderComponentContent {
  setSearchData: (schema: TableFormConfigSchema, value: any) => void
  formModel: Recordable
  field?: string
  schema: TableFormConfigSchema
}
export type BtnLayout =
  | 'btnSlotOne'
  | 'setBtn'
  | 'btnSlotTwo'
  | 'downBtn'
  | 'btnSlotThree'
  | 'reloadBtn'
  | 'btnSlotFour'

export interface FetchParams {
  searchInfo?: Recordable
  page?: number
  sortInfo?: Recordable
  filterInfo?: Recordable
}
export interface TableSetting {
  redo?: boolean
  form?: boolean
  size?: boolean
  setting?: boolean
  fullScreen?: boolean
}
export interface FetchSetting {
  // 请求接口当前页数
  pageField: string
  // 每页显示多少条
  sizeField: string
  // 请求结果列表字段  支持 a.b.c
  listField: string
  // 请求结果总数字段  支持 a.b.c
  totalField: string
}
export interface SorterResult {
  column: BasicColumn
  order: SortOrder
  field: string
  columnKey: string
}
export interface TableActionType {
  reload: (opt?: FetchParams) => Promise<void>
  setProps: (props: Partial<BasicTableProps>) => void
  getSize: () => SizeType
  setShowForm: (show: boolean) => Promise<void>
  getShowForm: () => boolean
  getDataSource: () => Recordable
  getRawDataSource: () => Recordable
  /**设置表格数据 */
  setTableData: <T extends Ref<Recordable<any>[]>>(values: T[]) => void
  setShowPagination: (show: boolean) => Promise<void>
  getShowPagination: () => boolean
  getPagination: () => PaginationPropsType | PaginationProps | boolean
  setPagination: (info: Partial<PaginationProps | PaginationPropsType>) => void
  getVxeTableRef: () => null
  getLoading: () => boolean
  setLoading: (bool: boolean) => void
  /**根据唯一的rowKey 动态删除指定行的数据.可用于不刷新整个表格而局部更新数据 */
  deleteSelectRowByKey: (key: string) => void
  /**可根据传入的 index 值决定插入数据行的位置，不传则是顺序插入，可用于不刷新整个表格而局部更新数据 */
  insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => Recordable[] | void
  /** 根据唯一的 rowKey 更新指定行的数据.可用于不刷新整个表格而局部更新数据 */
  updateTableDataRecord: (rowKey: string | number, record: Recordable) => Recordable | void
}

export type SizeType = '' | 'large' | 'default' | 'small'
